<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/1/25 0025
 * Time: 11:06
 */

function checkEmpty($value) {
    if (!isset($value))
        return true;
    if ($value === null)
        return true;
    if (trim($value) === "")
        return true;

    return false;
}

function getMillisecond(){
    list($s1,$s2)=explode(' ',microtime());
    return (float)sprintf('%.0f',(floatval($s1)+floatval($s2))*1000);
}

/**
 * @param $params
 * @return string
 *  @description 传入数组获取签名字符串
 *               按照 key 首字母排序
 */
function getSignContent($params) {
    ksort($params);

    $stringToBeSigned = "";
    $i = 0;
    foreach ($params as $k => $v) {
        if (false === checkEmpty($v) && "@" != substr($v, 0, 1)) {

            if ($i == 0) {
                $stringToBeSigned .= "$k" . "=" . "$v";
            } else {
                $stringToBeSigned .= "&" . "$k" . "=" . "$v";
            }
            $i++;
        }
    }

    unset ($k, $v);
    return $stringToBeSigned;
}


function str2bin($hexdata)
{
    $bindata="";
    for ($i=0;$i < strlen($hexdata);$i+=2) {
        $bindata.=chr(hexdec(substr($hexdata,$i,2)));
    }
    return $bindata;
}

/**
 * @param $data
 * @param int $hashIterations
 * @return string
 *   获取加密真正秘钥
 */
function sha256hashBase64($data , $hashIterations = 1024){
    $str = $data;
    for ($x=0; $x<$hashIterations; $x++) {
        $tar = hash("sha256" , $str);
        $str = str2bin($tar);
    }
    return base64_encode($str);
}



/**
 * 填充算法
 * @param string $source
 * @return string
 */
function addPKCS7Padding($source){
    $source = trim($source);
    $block = @mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $pad = $block - (strlen($source) % $block);
    if ($pad <= $block) {
        $char = chr($pad);
        $source .= str_repeat($char, $pad);
    }
    return $source;
}

/**
 * 移去填充算法
 * @param string $source
 * @return string
 */
function stripPKSC7Padding($source){
    $source = trim($source);
    $char = substr($source, -1);
    $num = ord($char);
    if($num==62)return $source;
    $source = substr($source,0,-$num);
    return $source;
}


function encrypt($str,$screct_key , $IVS= array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)){
    //AES, 128 模式加密数据 CBC
    $IVS = implode(array_map("chr", $IVS));
    $screct_key = getSercrtCode($screct_key);
    $screct_key = base64_decode($screct_key);
    $encrypt_str =openssl_encrypt($str, 'aes-128-cbc', $screct_key, true, $IVS);
    return base64_encode($encrypt_str);
}

/**
 * 解密方法
 * @param string $str
 * @return string
 */
function decrypt($str,$screct_key,$IVS= array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) ){
    //AES, 128 模式加密数据 CBC
    $str = base64_decode($str);
    $IVS = implode(array_map("chr", $IVS));
    $screct_key = getSercrtCode($screct_key);
    $screct_key = base64_decode($screct_key);
    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_CBC),1);
    // $encrypt_str =  mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $screct_key, $str, MCRYPT_MODE_CBC，$IVS );

    $encrypt_str =   mcrypt_decrypt (MCRYPT_RIJNDAEL_128, $screct_key, $str, MCRYPT_MODE_CBC, $IVS);
    $encrypt_str = trim($encrypt_str);
    $encrypt_str = stripPKSC7Padding($encrypt_str);
    return $encrypt_str;
}

function getSercrtCode($key){
    $key = sha256hashBase64($key);
    $key2 = substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16);
    return base64_encode($key2);
}


//此方法对value做urlencode
function getSignContentUrlencode($params) {
    ksort($params);
    $stringToBeSigned = "";
    $i = 0;
    foreach ($params as $k => $v) {
        if (false === checkEmpty($v) && "@" != substr($v, 0, 1)) {

            if ($i == 0) {
                $stringToBeSigned .= "$k" . "=" . urlencode($v);
            } else {
                $stringToBeSigned .= "&" . "$k" . "=" . urlencode($v);
            }
            $i++;
        }
    }
    unset ($k, $v);
    return $stringToBeSigned;
}


function curl($url, $postFields = null) {
    $postCharset = "UTF-8";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FAILONERROR, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $postBodyString = "";
    $encodeArray = Array();
    $postMultipart = false;

    if (is_array($postFields) && 0 < count($postFields)) {

        foreach ($postFields as $k => $v) {
            if ("@" != substr($v, 0, 1)) //判断是不是文件上传
            {

                $postBodyString .= "$k=" . urlencode( $v ) . "&";
                $encodeArray[$k] = $v;
            } else //文件上传用multipart/form-data，否则用www-form-urlencoded
            {
                $postMultipart = true;
                $encodeArray[$k] = new \CURLFile(substr($v, 1));
            }

        }
        unset ($k, $v);
        curl_setopt($ch, CURLOPT_POST, true);
        if ($postMultipart) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $encodeArray);
        } else {
            curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1));
        }
    }

    if ($postMultipart) {

        $headers = array('content-type: multipart/form-data;charset=' . $postCharset . ';boundary=' . $this->getMillisecond());
    } else {

        $headers = array('content-type: application/x-www-form-urlencoded;charset=' . $postCharset);
    }
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    $reponse = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception(curl_error($ch), 0);
    } else {
        $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if (200 !== $httpStatusCode) {
            throw new Exception($reponse, $httpStatusCode);
        }
    }
    curl_close($ch);
    return $reponse;
}